package reci.journal.windows;

import java.awt.*;
import java.awt.event.*;
import java.util.Arrays;

import javax.swing.*;
import javax.swing.border.TitledBorder;
import javax.swing.event.*;

import reci.journal.*;
import reci.journal.Const.Actions;
import reci.journal.utils.ExtUtil;
import reci.journal.utils.Util;

/*
 * Copyright (C) 2014 ReciGames
 * See notice in reci.journal.Main.java.
 */

public class MainWindow extends JFrame implements ActionListener, ChangeListener
{
	private static final long serialVersionUID = 1L;
	
	//parent
	private Main main;
	
	private Container contentPane;
	
	//tabs
	private String[] tabNames=new String[]{"Main","Settings"};
	private JPanel[] tabs=new JPanel[tabNames.length];
	private int currentTabIndex=-1;
	
	//fields
	private JPasswordField pass;
	private JPasswordField pass2;
	private JTextField filenameJ;
	private JTextField commandJ;
	private JTextField templateJ;
	
	/**
	 * @param m
	 */
	public MainWindow(Main m)
	{
		main=m;
		initUi("Main");
	}
	
	/**
	 * Destroys window.
	 */
	public void destroy()
	{
		this.setVisible(false);
		this.dispose();
	}
	
	/**
	 * Initializes UI to selectedTab.
	 * 
	 * @param selectedTab
	 */
	private void initUi(String selectedTab)
	{	
		//content pane stuff
		contentPane=getContentPane();
		contentPane.setLayout(null);
		contentPane.setBackground(new Color(0xccccff));
		
		try
		{
			UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
		}
		catch(Exception e)
		{
			
		}
		
		//JFrame stuff
		int frameWidth=400;
		int frameHeight=350;
		setDefaultCloseOperation(DO_NOTHING_ON_CLOSE);
		setSize(frameWidth,frameHeight);
		setLocationRelativeTo(null);
		setResizable(false);
		addWindowListener(new WindowAdapter()
		{
			public void windowClosing(WindowEvent e)
			{
				if(!apply())
				{
					showApplyError();
					return;
				}
				
				logout(Actions.EXIT);
			}
		});
		
		//tabbed pane
		JTabbedPane tabbedPane=new JTabbedPane(JTabbedPane.LEFT);
		tabbedPane.setBounds(0,0,frameWidth,frameHeight);
		tabbedPane.addChangeListener(this);
		contentPane.add(tabbedPane);
		
		//tabs
		for(int i=0; i<tabs.length; i++)
		{
			tabs[i]=new JPanel();
			tabs[i].setLayout(null);
			tabs[i].setBackground(Color.WHITE);
			tabs[i].setBorder(BorderFactory.createLineBorder(Color.BLACK,1));
			tabs[i].setVisible(false);
			tabbedPane.addTab(tabNames[i],tabs[i]);
		}
		
		//font for jwhatever text
		Font small=new Font("Arial",Font.PLAIN,10);
		Font font=new Font("Arial",Font.PLAIN,12);
		Font bold=new Font("Arial",Font.BOLD,12);
		JLabel jl;
		JButton jb;
		
		//Main tab
		{
			JPanel tab=tabs[0];
			
			//actions pane
			{
				JPanel pane=new JPanel();
				pane.setLayout(null);
				pane.setBounds(5,5,325,310);
				pane.setBackground(Color.WHITE);
				pane.setBorder(BorderFactory.createTitledBorder(BorderFactory.createLineBorder(Color.GRAY),"Actions",TitledBorder.LEFT,TitledBorder.TOP,new Font("Arial",Font.PLAIN,16),Color.GRAY));
				tab.add(pane);
				
				int px=75;
				int py=50;
				int w=175;
				int h=50;
				int hpm=h+5;//h+margin
				
				jb=new JButton("New Entry");
				jb.setBounds(px,py,w,h);
				jb.setFont(font);
				jb.addActionListener(this);
				pane.add(jb);
				
				jb=new JButton("View Journal");
				jb.setBounds(px,py+hpm,w,h);
				jb.setFont(font);
				jb.addActionListener(this);
				pane.add(jb);
				
				jb=new JButton("Help");
				jb.setBounds(px,py+2*hpm,w,h);
				jb.setFont(font);
				jb.addActionListener(this);
				pane.add(jb);
				
				jb=new JButton("Logout");
				jb.setBounds(px,py+3*hpm,w/2,h);
				jb.setFont(font);
				jb.addActionListener(this);
				pane.add(jb);
				
				jb=new JButton("Exit");
				jb.setBounds(px+w/2+5,py+3*hpm,w/2-2,h);
				jb.setFont(font);
				jb.addActionListener(this);
				pane.add(jb);
			}
		}
		//Settings tab
		{
			JPanel tab=tabs[1];
			
			//password pane
			{
				JPanel pane=new JPanel();
				pane.setLayout(null);
				pane.setBounds(5,5,325,130);
				pane.setBackground(Color.WHITE);
				pane.setBorder(BorderFactory.createTitledBorder(BorderFactory.createLineBorder(Color.GRAY),"Change Password",TitledBorder.LEFT,TitledBorder.TOP,new Font("Arial",Font.PLAIN,16),Color.GRAY));
				tab.add(pane);
				
				int px=10;
				int py=-5;
				
				jl=new JLabel("Password");
				jl.setBounds(0+px,20+py,200,30);
				jl.setFont(bold);
				pane.add(jl);
				
				jl=new JLabel("(keep blank for no password)",SwingConstants.RIGHT);
				jl.setBounds(0+px,20+py,200,30);
				jl.setFont(small);
				pane.add(jl);
				
				String password=Journal.getPassword();
				pass=new JPasswordField(password);
				pass.setBounds(0+px,45+py,200,30);
				pane.add(pass);
				
				jl=new JLabel("Confirm password");
				jl.setBounds(0+px,70+py,200,30);
				jl.setFont(bold);
				pane.add(jl);
				
				pass2=new JPasswordField(password);
				pass2.setBounds(0+px,95+py,200,30);
				pane.add(pass2);
			}
			
			//entry pane
			{
				JPanel pane=new JPanel();
				pane.setLayout(null);
				pane.setBounds(5,135,325,180);
				pane.setBackground(Color.WHITE);
				pane.setBorder(BorderFactory.createTitledBorder(BorderFactory.createLineBorder(Color.GRAY),"Entry",TitledBorder.LEFT,TitledBorder.TOP,new Font("Arial",Font.PLAIN,16),Color.GRAY));
				tab.add(pane);
				
				int px=10;
				int py=15;
				String macroTooltip="accepts macros";
				
				//template path
				jl=new JLabel("Template Path *");
				jl.setToolTipText(macroTooltip);
				jl.setBounds(0+px,0+py,200,30);
				jl.setFont(bold);
				pane.add(jl);

				String templatePath=Journal.templatePathMacro;
				templateJ=new JTextField(templatePath);
				templateJ.setBounds(0+px,25+py,200,30);
				pane.add(templateJ);
				
				jb=new JButton("Browse");
				jb.setBounds(205+px,25+py,100,30);
				jb.setFont(font);
				jb.addActionListener(this);
				pane.add(jb);
				
				//new entry path
				jl=new JLabel("New Entry Path *");
				jl.setToolTipText(macroTooltip);
				jl.setBounds(0+px,50+py,200,30);
				jl.setFont(bold);
				pane.add(jl);
				
				String filenameMacro=Journal.newEntryPathMacro;
				filenameJ=new JTextField(filenameMacro);
				filenameJ.setBounds(0+px,75+py,305,30);
				pane.add(filenameJ);
				
				//new entry command
				jl=new JLabel("New Entry Command *");
				jl.setToolTipText(macroTooltip);
				jl.setBounds(0+px,100+py,200,30);
				jl.setFont(bold);
				pane.add(jl);
				
				jl=new JLabel("(keep blank for default)",SwingConstants.RIGHT);
				jl.setBounds(100+px,100+py,200,30);
				jl.setFont(small);
				pane.add(jl);
				
				String newEntryCommandMacro=Journal.newEntryCommandMacro;
				commandJ=new JTextField(newEntryCommandMacro);
				commandJ.setBounds(0+px,125+py,305,30);
				pane.add(commandJ);
			}
		}
		
		setVisible(true);
	}
	
	private boolean isAutoChangingTab=false;
	
	/**
	 * Switched panes.
	 */
	@Override
	public void stateChanged(ChangeEvent e)
	{
		//verify settings
		if(!isAutoChangingTab && currentTabIndex==1)
		{
			if(!apply())
			{
				isAutoChangingTab=true;
				((JTabbedPane)e.getSource()).setSelectedIndex(currentTabIndex);
				isAutoChangingTab=false;
				showApplyError();
				return;
			}
		}
		
		currentTabIndex=((JTabbedPane)e.getSource()).getSelectedIndex();
		setTitle(Const.APP_NAME+": "+tabNames[currentTabIndex]);
	}
	
	@Override
	public void actionPerformed(ActionEvent e)
	{
		if(e.getSource() instanceof JButton)
		{
			String text=((JButton)e.getSource()).getText();
			
			//Main
			if(currentTabIndex==0)
			{
				if(text.equals("New Entry"))
				{
					Journal.createEntry();
				}
				else if(text.equals("View Journal"))
				{
					ExtUtil.openFile(Journal.journalRoot);
				}
				else if(text.equals("Help"))
				{
					ExtUtil.openLink("http://recigames.com/s/recijournal/manual.html");
				}
				else if(text.equals("Logout"))
				{
					logout(Actions.LOGOUT);
				}
				else if(text.equals("Exit"))
				{
					logout(Actions.EXIT);
				}
			}
			//entries
			else if(currentTabIndex==1)
			{
				if(text.equals("Browse"))
				{
					browseForTemplate();
				}
			}
		}
	}
	
	/**
	 * Browse for a template.
	 */
	private void browseForTemplate()
	{
		try
		{
			JFileChooser chooser=new JFileChooser(Journal.journalRoot);
			chooser.showOpenDialog(null);
			String path=chooser.getSelectedFile().getAbsolutePath();
			
			if(path.startsWith(Journal.journalRoot))
			{
				path=path.substring(Journal.journalRoot.length());
			}
			
			templateJ.setText(path);
		}
		catch(Exception ex)
		{}
	}
	
	private String applyError=null;
	
	/**
	 * Apply settings.
	 * 
	 * @return success
	 */
	private boolean apply()
	{
		//
		// verify changes
		//
		
		//if passwords don't match
		char[] p1=pass.getPassword();
		char[] p2=pass2.getPassword();
		
		if(!Arrays.equals(p1,p2))
		{
			applyError="Passwords do not match.";
			pass.requestFocus();
			//pass.selectAll();
			return false;
		}
		
		//if New Entry Path blank
		if(filenameJ.getText().equals(""))
		{
			applyError="New Entry Path must be set.";
			filenameJ.requestFocus();
			return false;
		}
		
		//
		// apply changes
		//
		
		Journal.setPassword(p1);
		//p1 is kept as Journal.password, so don't clear it
		Arrays.fill(p2,(char)0);
		
		Journal.setNewFileNameMacro(filenameJ.getText());
		Journal.setNewEntryCommandMacro(commandJ.getText());
		Journal.setTemplatePathMacro(templateJ.getText());
		
		return true;
	}
	
	/**
	 * Shows error when trying to apply invalid settings.
	 */
	private void showApplyError()
	{
		if(applyError!=null)
		{
			Util.alert(applyError);
		}
		
		//reset
		applyError=null;
	}
	
	/**
	 * Logs out.
	 * 
	 * @param action
	 */
	private void logout(Actions action)
	{
		boolean isReady=true;
		
		try
		{
			setCursor(Cursor.getPredefinedCursor(Cursor.WAIT_CURSOR));
			isReady=Journal.logout();
		}
		catch(Exception e)
		{
			Util.alert("Error logging out.",e);
		}
		finally
		{
			setCursor(Cursor.getDefaultCursor());
		}
		
		if(isReady)
		{
			destroy();
			
			if(action==Actions.LOGOUT)
			{
				new LoginWindow(main);
			}
			else if(action==Actions.EXIT)
			{
				main.destroy();
			}
		}
	}
}
